package com.shelpe.services.sinbad.controller;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.math.NumberUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.shelpe.services.sinbad.entity.jpa.TaskProgress;
import com.shelpe.services.sinbad.entity.jpa.TaskProgress.Status;
import com.shelpe.services.sinbad.entity.jpa.TemplateTags;
import com.shelpe.services.sinbad.repository.jpa.TaskProgressRepository;
import com.shelpe.services.sinbad.repository.jpa.TemplateTagsRepository;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;

@Controller
@RequestMapping("/sinbadservice")
@Slf4j
@Api(value = "人群设置相关和任务和用户数据最近同步的时间的API", consumes = "application/json", produces = "application/json")
public class CrowdDimisionController {
	@Autowired
	private TemplateTagsRepository templateTagsRepository;
	@Autowired
	private TaskProgressRepository taskProgressRepository;

	@ApiOperation(value = "创建任务")
	@RequestMapping(method = RequestMethod.POST, path = "/tasks")
	@ResponseBody
	public TaskDto createTask(@RequestBody TaskDto dto) {
		TaskProgress task = new TaskProgress();
		BeanUtils.copyProperties(dto, task);
		task.setStartTime(new Date());
		task.setEndTime(new Date());
		task.setUpdateTime(new Date());
		task.setStatus(Status.from(dto.getStatus()));

		this.taskProgressRepository.save(task);
		log.debug("finish create task:{}", task);
		return dto;
	}

	@ApiOperation(value = "更新任务")
	@RequestMapping(method = RequestMethod.PUT, path = "/tasks/{task_id}")
	@ResponseBody
	public TaskDto updateTask(@PathVariable("task_id") String taskID, @RequestBody TaskDto dto) {
		TaskProgress task = this.taskProgressRepository.findOne(taskID);
		Assert.notNull(task, "task_not_exist");
		if (StringUtils.isNotBlank(dto.getMessage())) {
			task.setMessage(dto.getMessage());
		}
		task.setUpdateTime(new Date());
		task.setStatus(Status.from(dto.getStatus()));
		this.taskProgressRepository.save(task);
		BeanUtils.copyProperties(task, dto);
		log.debug("finish update task:{}", task);
		return dto;
	}

	@ApiOperation(value = "查找任务")
	@RequestMapping(method = RequestMethod.GET, path = "/tasks/{task_id}")
	@ResponseBody
	public TaskDto findTask(@PathVariable("task_id") String taskID) {
		TaskDto dto = new TaskDto();
		TaskProgress task = this.taskProgressRepository.findOne(taskID);
		Assert.notNull(task, "task_not_exist");
		BeanUtils.copyProperties(dto, task);
		dto.setStatus(task.getStatus().name());
		log.debug("finish find task:{}", task);
		return dto;
	}

	@Data
	public static class TaskDto {
		@JsonProperty("task_id")
		private String taskID;
		private String taskName;
		@JsonProperty("user_id")
		private long userID;
		private long processedNum;
		private long totalNum;
		private String status;
		@JsonProperty("sem_id")
		private long semID;
		private String message;
		@JsonProperty("container_id")
		private long containerID;
		@JsonProperty("container_type")
		private String containerType;
		private int isNeedSync; // 是否需要同步。0不需要 1需要
		@JsonProperty("product_id")
		private long productID;
	}

	/**
	 * 批量导入人群自定义模板
	 * 
	 * @param dto
	 * @return
	 */
	@ApiOperation(value = "批量导入人群自定义模板")
	@RequestMapping(method = RequestMethod.POST, path = "/crowdTemplates/@batchImport")
	@ResponseBody
	public List<TemplateTags> crowdTemplateImport(@RequestBody TemplateDto dto) {
		log.debug("start import template:{}", dto);
		List<TemplateTags> existings = this.templateTagsRepository.findByTemplateName(dto.getTemplateName());

		List<TemplateTags> newTags = new ArrayList<TemplateTags>();
		for (TagList tag : dto.getTagList()) {
			TemplateTags existing = this.filterByDimID(existings, tag.getDimID(), tag.getTagID());

			if (existing != null) {
				existing.setDimID(tag.getDimID());
				existing.setDimName(tag.getDimName());
				existing.setOptionGroupID(tag.getOptionGroupID());
				existing.setSource(TemplateTags.SOURCE_MANUAL);
				existing.setTagID(tag.getTagID());
				existing.setTagName(tag.getTagName());
				existing.setTemplateID(NumberUtils.toLong(dto.getTemplateID()));
				existing.setTemplateName(dto.getTemplateName());
				existing.setSyncDate(new Date());
				newTags.add(existing);
			} else {
				TemplateTags templateTag = new TemplateTags();
				templateTag.setDimID(tag.getDimID());
				templateTag.setDimName(tag.getDimName());
				templateTag.setOptionGroupID(tag.getOptionGroupID());
				templateTag.setTemplateName(dto.getTemplateName());
				templateTag.setTemplateID(NumberUtils.toLong(dto.getTemplateID()));
				templateTag.setTagName(tag.getTagName());
				templateTag.setTagID(tag.getTagID());
				templateTag.setSyncDate(new Date());
				templateTag.setSource(TemplateTags.SOURCE_MANUAL);
				existings.add(templateTag);
				newTags.add(templateTag);
			}
		}

		this.templateTagsRepository.save(existings);
		log.debug("finish create crowdTemplateImport:{}", existings);

		return newTags;
	}

	private TemplateTags filterByDimID(List<TemplateTags> dims, long dimID, long tagID) {
		for (TemplateTags dim : dims) {
			if (dim.getDimID() == dimID && dim.getTagID() == tagID) {
				return dim;
			}
		}
		return null;
	}

	/**
	 * 查看人群模板详细
	 * 
	 * @param templateID
	 * @return
	 */
	@ApiOperation(value = "查看人群模板详细")
	@RequestMapping(method = RequestMethod.GET, path = "/crowdTemplates/{template_id}")
	@ResponseBody
	public CrowdDto findCrowdDetail(@PathVariable("template_id") long templateID) {
		Assert.isTrue(templateID > 0, "invalid_template_id");
		List<TemplateTags> dims = this.templateTagsRepository.findByTemplateID(templateID);
		Map<Long, List<TemplateTags>> TemplateTags = new HashMap<Long, List<TemplateTags>>();
		for (TemplateTags dimTag : dims) {
			List<TemplateTags> tagOptions = TemplateTags.get(dimTag.getDimID());
			if (tagOptions == null) {
				tagOptions = new ArrayList<TemplateTags>();
				TemplateTags.put(dimTag.getDimID(), tagOptions);
			}
			tagOptions.add(dimTag);
		}

		CrowdDto dto = new CrowdDto();
		dto.setTemplateID(templateID);
		dto.setTagOptions(new ArrayList<TagOption>());
		for (Map.Entry<Long, List<TemplateTags>> entry : TemplateTags.entrySet()) {
			TagOption tagOption = new TagOption();
			tagOption.setTags(new ArrayList<Tags>());
			dto.from(entry.getValue(), tagOption);
			dto.getTagOptions().add(tagOption);
		}
		return dto;
	}

	/**
	 * 获取人群导航模板
	 * 
	 * @return
	 */
	@ApiOperation(value = "获取人群导航模板")
	@RequestMapping(method = RequestMethod.GET, path = "/crowdTemplates")
	@ResponseBody
	public HashSet<CrowdTemplateDto> findTemplate() {
		HashSet<CrowdTemplateDto> dtos = new HashSet<CrowdTemplateDto>();
		Iterable<TemplateTags> dims = this.templateTagsRepository.findAll();
		for (TemplateTags dim : dims) {
			CrowdTemplateDto dto = new CrowdTemplateDto();
			dto.setTemplateID(dim.getTemplateID());
			dto.setTemplateName(dim.getTemplateName());
			dtos.add(dto);
		}
		return dtos;
	}

	@Data
	@JsonInclude(Include.NON_NULL)
	public static class CrowdTemplateDto {
		@JsonProperty("template_id")
		private long templateID;
		@JsonProperty("template_name")
		private String templateName;
	}

	@Data
	@JsonInclude(Include.NON_NULL)
	public static class CrowdDto {
		@JsonProperty("template_id")
		private long templateID;
		@JsonProperty("template_name")
		private String templateName;
		@JsonProperty("tag_options")
		private List<TagOption> tagOptions;

		public void addOptions(TagOption tagOption) {
			if (this.tagOptions == null) {
				this.tagOptions = new ArrayList<TagOption>();
			}
			this.tagOptions.add(tagOption);
		}

		public void from(List<TemplateTags> dims, TagOption tagOption) {
			if (dims != null) {
				for (TemplateTags dim : dims) {
					this.setTemplateName(dim.getTemplateName());
					Tags tag = new Tags();
					tag.setDimID(dim.getDimID());
					tag.setOptionGroupID(dim.getOptionGroupID());
					tag.setTagID(dim.getTagID());
					tag.setTagName(dim.getTagName());
					tagOption.getTags().add(tag);

					tagOption.setDimID(dim.getDimID());
					tagOption.setDimName(dim.getDimName());
				}
			}
		}
	}

	@Data
	@JsonInclude(Include.NON_NULL)
	public static class TagOption {
		@JsonProperty("dim_id")
		private long dimID;
		@JsonProperty("dim_name")
		private String dimName;

		private List<Tags> tags;

		public void addTag(Tags tag) {
			if (this.tags == null) {
				this.tags = new ArrayList<Tags>();
			}
			this.tags.add(tag);
		}
	}

	@Data
	@JsonInclude(Include.NON_NULL)
	public static class Tags {
		@JsonProperty("dim_id")
		private long dimID; // 标签所属的维度id
		@JsonProperty("tag_id")
		private long tagID; // 标签id
		@JsonProperty("tag_name")
		private String tagName; // 维度名称,如性别,年龄
		@JsonProperty("option_group_id")
		private long optionGroupID; // 维度id,如性别年龄的id
	}

	@Data
	@JsonInclude(Include.NON_NULL)
	public static class TemplateDto {
		@JsonProperty("templateId")
		private String templateID;
		@JsonProperty("name")
		private String templateName;
		@JsonProperty("tagList")
		private List<TagList> tagList;

		public void addTag(TagList tag) {
			if (this.tagList == null) {
				this.tagList = new ArrayList<TagList>();
			}
			this.tagList.add(tag);
		}
	}

	@Data
	@JsonInclude(Include.NON_NULL)
	public static class TagList {
		@JsonProperty("dimId")
		private long dimID; // 标签所属的维度id
		@JsonProperty("dimName")
		private String dimName;
		@JsonProperty("tagId")
		private long tagID; // 标签id
		@JsonProperty("tagName")
		private String tagName; // 维度名称,如性别,年龄
		@JsonProperty("optionGroupId")
		private long optionGroupID; // 维度id,如性别年龄的id

	}
}
